package com.jxpay.fupay;


import com.jxpay.fupay.core.SignUtils;
import com.jxpay.fupay.enums.FuApiType;
import com.jxpay.fupay.enums.FuDomain;
import cn.hutool.core.date.DateUtil;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

//import org.apache.shiro.crypto.RandomNumberGenerator;
//import org.apache.shiro.crypto.SecureRandomNumberGenerator;

/**
 * <p>JXPay-银盛支付</p>
 *
 * @author JX
 */
public class FuPayApi {
	//private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
  
	private FuPayApi() {
    }

    /**
     * 获取接口请求的 URL
     *
     * @param wxApiType {@link WxApiType} 支付 API 接口枚举
     * @return {@link String} 返回完整的接口请求URL
     */
    public static String getReqUrl(FuApiType fuApiType) {
        return getReqUrl(fuApiType, null, false);
    }

    /**
     * 获取接口请求的 URL
     *
     * @param wxApiType {@link WxApiType} 支付 API 接口枚举
     * @param isSandBox 是否是沙箱环境
     * @return {@link String} 返回完整的接口请求URL
     */
    public static String getReqUrl(FuApiType fuApiType, boolean isSandBox) {
        return getReqUrl(fuApiType, null, isSandBox);
    }

    /**
     * 获取接口请求的 URL
     *
     * @param wxApiType {@link WxApiType} 支付 API 接口枚举
     * @param wxDomain  {@link WxDomain} 支付 API 接口域名枚举
     * @param isSandBox 是否是沙箱环境
     * @return {@link String} 返回完整的接口请求URL
     */
    public static String getReqUrl(FuApiType fuApiType, FuDomain fuDomain, boolean isSandBox) {
        if (fuDomain == null) {
        	fuDomain = FuDomain.CHINA;
        }
        return fuDomain.getType()
                .concat(isSandBox ? FuApiType.SAND_BOX_NEW.getType() : "")
                .concat(fuApiType.getType());
    }
    
    public static String doGet(String url, Map<String, String> params) {
		return url;
        //return HttpClientUtil.sendPost(url, params);
    }

    public static String doPost(String url, Map<String, String> params) {
		return url;
        //return HttpClientUtil.sendPost(url, params);
    }
    /**
     * 发起请求
     *
     * @param apiUrl 接口 URL
     *               通过 {@link FuPayApi#getReqUrl(FuApiType)}
     *               或者 {@link FuPayApi#getReqUrl(FuApiType, FuDomain, boolean)} 来获取
     * @param params 接口请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String execution(String apiUrl, Map<String, String> params) {
        return doPost(apiUrl, params);
    }

    /**
     * 发起请求
     *
     * @param apiUrl 接口 URL
     *               通过 {@link FuPayApi#getReqUrl(FuApiType)}
     *               或者 {@link FuPayApi#getReqUrl(FuApiType, FuDomain, boolean)} 来获取
     * @param params 接口请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String executionByGet(String apiUrl, Map<String, String> params) {
        return doGet(apiUrl, params);
    }

    public static String switch_pay_type(Integer payType) {
        //订单类型:ALIPAY , WECHAT,
        //QQ(QQ钱包)，UNIONPAY(银联二维码)，BESTPAY(翼支付)
        switch(payType) {
            case 2:
                return "ALIPAY";
            case 3:
                return "QQ";
            case 1:
                return "WECHAT";
            case 4:
                return "BANK";                
            default:
                return "WECHAT";
        }
    }

    /**
     * V3 接口统一执行入口
     *
     * @param method    {@link Method} 请求方法
     * @param urlPrefix 可通过 {@link FuDomain}来获取
     * @param mchId     商户Id
     * @param serialNo  商户 API 证书序列号
     * @param keyPath   apiclient_key.pem 证书路径
     * @param body      接口请求参数
     * @param nonceStr  随机字符库
     * @param timestamp 时间戳
     * @param authType  认证类型
     * @return {@link String} 请求返回的结果
     * @throws Exception 接口执行异常
     */
    public static String v3Execution(String urlPrefix, String partnerId, String charset, String signType, String notifyUrl, String version,String privateKey,String publicKey,Map<String,String> bizContent) throws Exception {
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        map.put("version", version);
        map.put("ins_cd",partnerId);
        map.put("mchnt_cd", bizContent.get("mchnt_cd"));
        map.put("term_id", bizContent.get("term_id"));
        map.put("random_str","");
        map.put("sign", "");
        
        map.put("order_type", switch_pay_type(Integer.valueOf(bizContent.get("order_type"))));
        map.put("goods_des", bizContent.get("context"));
        map.put("goods_detail",bizContent.get("goods_detail"));
        map.put("addn_inf", "");
        Calendar calendar = Calendar.getInstance();
        map.put("mchnt_order_no", bizContent.get("OutOrderId"));//sdf_no.format(calendar.getTime()) + (int)(random.nextDouble() * 100000));
        map.put("curr_type", "");
        BigDecimal amt = new BigDecimal("100");
        amt = amt.multiply(new BigDecimal(bizContent.get("price"))).setScale(0, BigDecimal.ROUND_HALF_UP);
        map.put("order_amt", String.valueOf(amt));//总金额, 订单总金额，单位为分
        SimpleDateFormat sdf_ts = new SimpleDateFormat("yyyyMMddHHmmss");
        map.put("txn_begin_ts", sdf_ts.format(calendar.getTime()));
        map.put("goods_tag", "");
        map.put("auth_code", bizContent.get("authCode"));//扫码支付授权码，设备读取用户的条码或者二维码信息.
        map.put("sence","");//支付场景,默认1；条码支付:1 声波支付:2
        map.put("reserved_sub_appid","");//子商户公众号id(后期拓展字段，请先不要填写)
        map.put("reserved_limit_pay","");//限制支付,no_credit:不能使用信用卡
        map.put("reserved_expire_minute", "");//交易关闭时间,如不设置，默认填0单位:分钟 最大值为1440  例如:1天=1440
        map.put("reserved_fy_term_id","");//富友终端号(如果不是用的富友的POS终端，此字段千万不要填，不然会影响清算）
        map.put("reserved_fy_term_type","");//0:其他1:富友终端2:POS机3:台卡4:PC软件
        map.put("reserved_fy_term_sn","");//终端序列号        
        String ret = SignUtils.run(map, urlPrefix ,charset,privateKey,publicKey);
        return ret;//SignUtils.xmlStr2Map(ret);
    }

    public static String apiPay(String method,FuPayApiConfig ysConfig, Map<String, String> params) {   	
    	try {
			return v3Execution(method,ysConfig.getInscd(), ysConfig.getCharset(),ysConfig.getSignType(),ysConfig.getNotifyUrl(),ysConfig.getVer(),ysConfig.getPrivateKey(),ysConfig.getPublicKey(),params);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return null;
		}
    }

    
    public static String apiPay(String method,Map<String, String> params) {   	
        return apiPay(method,FuPayApiConfigKit.getFuPayApiConfig(),params);
    }    
    
    /**
     * 刷卡支付
     *
     * @param params    请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String microPay(Map<String, String> params) {   	
        return apiPay(getReqUrl(FuApiType.MICRO_PAY),params);
    }    
    /**
     * 订单查询
     *
     * @param params 请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String orderQuery(Map<String, String> params) {
        return orderQuery(false,  params);
    }
    
    /**
     * 订单查询
     *
     * @param isSandbox 是否是沙盒环境
     * @param params    请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String orderQuery(boolean isSandbox, Map<String, String> params) {
        return apiPay(getReqUrl(FuApiType.ORDER_QUERY,null, isSandbox), params);
    }

    /**
     * 查询退款
     *
     * @param isSandbox 是否是沙盒环境
     * @param params    请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String orderRefundQuery(Map<String, String> params) {
        return apiPay(getReqUrl(FuApiType.REFUND_QUERY,null, false), params);
    }

    /**
     * 查询退款
     *
     * @param isSandbox 是否是沙盒环境
     * @param params    请求参数
     * @return {@link String} 请求返回的结果
     */
    public static String orderRefundQuery(boolean isSandbox, Map<String, String> params) {
        return apiPay(getReqUrl(FuApiType.REFUND_QUERY,null, isSandbox), params);
    }



    public static void main(String[] args) {
    	FuPayApiConfig ys =FuPayApiConfig.builder().appId("826581173720001")
    			.inscd("826581173720001")
    			.charset("GBK")
    			.signType("RSA")
    			.ver("3.0")
    			.notifyUrl("http://data.jiangxinit.com/pay/notify/ys/callbak")
    			.privateKey("F:\\agile\\king\\git\\pigx\\jxplus\\cert\\ys.pfx")
    			.publicKey("815815")
    			.build();
    	FuPayApiConfigKit.putApiConfig(ys);
        System.out.println(setBarcodePay());
    }

    public static String setBarcodePay() {
        Map<String,String> bizContent = new HashMap<>();
        bizContent.put("shopdate", DateUtil.format(new Date(),"yyyyMMdd"));
        bizContent.put("total_amount", "0.01");
        bizContent.put("seller_id", "826581173720001");
        bizContent.put("seller_name", "广州匠心互动科技有限公司");
        bizContent.put("out_trade_no", "2020020500240002");
        bizContent.put("subject", "条码支付测试");
        bizContent.put("timeout_express", "1d");
        bizContent.put("bank_type", "1902000");
        bizContent.put("business_code", "01000010");
        bizContent.put("auth_code", "134658589963125937");
        String response =FuPayApi.microPay(bizContent);
        System.out.println("结果：:"+response);
        //银盛回调信息:{"notify_time":"2020-02-05 19:01:41","payee_fee":"0.00","account_date":"20200205","openid":"oVWdhs8ZM_9O0dJG8v0QPjY-TS8o","fee":"0.00","sign":"oODuFAyUFU7xpqn3YDuunp3ZU1r7D111zfzicxB3mTHYGx9GqSL8/UHso1jdC6gimVnwhxsNmipbpmHd3BqtUP4aEHKTRuyT6ZDwba14Ln5HyATXbXShrS+baA9iqS9FUfREdor7CzX1m0brNXRx5y7VdJTOIcZ+RjliijJcTos=","channel_send_sn":"1012002058897565271","card_type":"","notify_type":"directpay.status.sync","partner_fee":"0.00","out_trade_no":"2020020500240002","total_amount":"0.01","trade_status":"TRADE_SUCCESS","trade_no":"01O200205889756527","settlement_amount":"0.01","paygate_no":"9000010","sign_type":"RSA","payer_fee":"0.00","channel_recv_sn":"4200000496202002052970879207"}        
        return "";

    }    
}
